/*+--------------------------------------------------------------------------
Copyright (c) 2015, Microsoft Corporation 
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/

`timescale 1ns / 1ps
///////////////////////////////////////////////////////////////////////////////
// 
// Summary:
//
// The DDR_8TO1_16CHAN_RX module contains logic for LVDS Receiver,
// including 5 channels of LVDS data, one channel of LVDS clock, a clock/data 
// alignment algorithm, control circuit to share the alignment machine among
// all 5 data channels, and tap counters that keep track of the IDELAY tap
// setting of all data channels.
//  
//----------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////

module RCB_FRL_DDR_8TO1_16CHAN_RX
(
		input			RXCLK,
		input			RXCLKDIV,
		input			RESET,
		input			IDLY_RESET,
		
		input [4:0]	DATA_RX_P,
		input	[4:0]	DATA_RX_N,
		input			INC_PAD,
		input			DEC_PAD,
		input			BITSLIP_PAD,
		
		output [39:0]	DATA_FROM_ISERDES,
		output [5:0]	TAP_00,
		output [5:0]	TAP_01,
		output [5:0]	TAP_02,
		output [5:0]	TAP_03,
		output [5:0]	TAP_04,
		output [5:0]	TAP_CLK,
		output			TRAINING_DONE
	);


wire	[4:0]	DATA_RX_BUF;
wire	[4:0]	DATA_RX_IDLY;
wire		BITSLIP_FROM_MACHINE;
wire		ICE_FROM_MACHINE;
wire		INC_FROM_MACHINE;
wire		DATA_ALIGNED;
wire	[4:0]	SHIFT1;
wire	[4:0]	SHIFT2;
wire	[3:0]	CHAN_SEL;

reg	[4:0]	INC_CAPTURE;
reg	[4:0]	DEC_CAPTURE;
reg	[4:0]	BITSLIP_CAPTURE;
reg		INC_PULSE;
reg		DEC_PULSE;
reg		BITSLIP_PULSE;
reg	[20:0]	RESET_SM;
reg	[4:0]	BITSLIP_TO_ISERDES;
reg	[4:0]	ICE_TO_ISERDES;
reg	[4:0]	INC_TO_ISERDES;
reg	[7:0]	DATA_TO_MACHINE;

integer	I;

assign	INC_DELAY	= INC_PULSE;
assign	ICE_DELAY	= INC_PULSE || DEC_PULSE;
assign	TAP_CLK 		= 6'h01;			//CLOCK DELAY IS NOT ADJUSTED IN THIS REFERENCE DESIGN


//CHANNEL SELECT LOGIC TO SHARE ALIGNMENT MACHINE RESOURCES IN ROUND ROBIN FASHION
always @(posedge RXCLKDIV) begin
	case (CHAN_SEL)
		4'b0000: begin
				DATA_TO_MACHINE <= DATA_FROM_ISERDES[7:0];
				INC_TO_ISERDES <= {15'b000000000000000, INC_FROM_MACHINE};
				ICE_TO_ISERDES <= {15'b000000000000000, ICE_FROM_MACHINE};
				BITSLIP_TO_ISERDES <= {15'b000000000000000, BITSLIP_FROM_MACHINE};
			end
		
		4'b0001: begin
				DATA_TO_MACHINE <= DATA_FROM_ISERDES[15:8];
				INC_TO_ISERDES <= {14'b00000000000000, INC_FROM_MACHINE, 1'b0};
				ICE_TO_ISERDES <= {14'b00000000000000, ICE_FROM_MACHINE, 1'b0};
				BITSLIP_TO_ISERDES <= {14'b00000000000000, BITSLIP_FROM_MACHINE, 1'b0};
			end
		
		4'b0010: begin
				DATA_TO_MACHINE <= DATA_FROM_ISERDES[23:16];
				INC_TO_ISERDES <= {13'b0000000000000, INC_FROM_MACHINE, 2'b00};
				ICE_TO_ISERDES <= {13'b0000000000000, ICE_FROM_MACHINE, 2'b00};
				BITSLIP_TO_ISERDES <= {13'b0000000000000, BITSLIP_FROM_MACHINE, 2'b00};
			end
		
		4'b0011: begin
				DATA_TO_MACHINE <= DATA_FROM_ISERDES[31:24];
				INC_TO_ISERDES <= {12'b000000000000, INC_FROM_MACHINE, 3'b000};
				ICE_TO_ISERDES <= {12'b000000000000, ICE_FROM_MACHINE, 3'b000};
				BITSLIP_TO_ISERDES <= {12'b000000000000, BITSLIP_FROM_MACHINE, 3'b000};
			end
		4'b0100: begin
				DATA_TO_MACHINE <= DATA_FROM_ISERDES[39:32];
				INC_TO_ISERDES <= {11'b00000000000, INC_FROM_MACHINE, 4'b0000};
				ICE_TO_ISERDES <= {11'b00000000000, ICE_FROM_MACHINE, 4'b0000};
				BITSLIP_TO_ISERDES <= {11'b00000000000, BITSLIP_FROM_MACHINE, 4'b0000};
			end
	endcase
end

//MACHINE THAT ALLOCATES BIT_ALIGN_MACHINE TO EACH OF THE 5 DATA CHANNELS, ONE AT A TIME	
RCB_FRL_RESOURCE_SHARING_CONTROL RCB_FRL_RESOURCE_SHARING_CONTROL_inst (
	.CLK							(RXCLKDIV),
	.RST							(RESET),
	.CHAN_SEL					(CHAN_SEL),
	.START_ALIGN				(START_ALIGN),
	.DATA_ALIGNED				(DATA_ALIGNED),
	.ALL_CHANNELS_ALIGNED	(TRAINING_DONE)
);	

//MACHINE THAT ADJUSTS DELAY OF A SINGLE DATA CHANNEL TO OPTIMIZE SAMPLING POINT 
RCB_FRL_BIT_ALIGN_MACHINE RCB_FRL_BIT_ALIGN_MACHINE_inst (
	.RXCLKDIV		(RXCLKDIV),
	.RST				(RESET||RESET_SM[15]),
	.RXDATA			(DATA_TO_MACHINE),
	.USE_BITSLIP	(1'b1),
	.SAP				(START_ALIGN),
	.INC				(INC_FROM_MACHINE),
	.ICE				(ICE_FROM_MACHINE),
	.BITSLIP			(BITSLIP_FROM_MACHINE),
	.DATA_ALIGNED	(DATA_ALIGNED)
); 	

//SHORTEN EACH EXTERNAL INC AND DEC PULSE TO ONE RXCLKDIV CYCLE
always @(posedge RXCLKDIV) begin						
	INC_CAPTURE[0] <= INC_PAD;			//ASYNCHRONOUS ENTRY POINT
	DEC_CAPTURE[0] <= DEC_PAD;
	BITSLIP_CAPTURE[0] <= BITSLIP_PAD;
	begin
		for(I = 0; I <= 3 - 1; I = I + 1)
		begin
			INC_CAPTURE[I + 1] <= INC_CAPTURE[I];	//METASTABLE FLIP-FLOPS
			DEC_CAPTURE[I + 1] <= DEC_CAPTURE[I];	
			BITSLIP_CAPTURE[I + 1] <= BITSLIP_CAPTURE[I];	
		end
	end
	INC_PULSE <= INC_CAPTURE[2] & ~INC_CAPTURE[3];	//STABLE, SINGLE PULSE
	DEC_PULSE <= DEC_CAPTURE[2] & ~DEC_CAPTURE[3];	
	BITSLIP_PULSE <= BITSLIP_CAPTURE[2] & ~BITSLIP_CAPTURE[3];
end
   
//KEEP TRACK OF CURRENT TAP SETTING OF IDELAY IN DATA PATH OF CHANNELS 00-04
RCB_FRL_COUNT_TO_64 TAP_COUNTER_00(
	.clk(RXCLKDIV), 
	.rst(IDLY_RESET||RESET), 
	.count(ICE_DELAY||ICE_TO_ISERDES[00]), 
	.ud(INC_DELAY||INC_TO_ISERDES[00]), 
	.counter_value(TAP_00)
);
RCB_FRL_COUNT_TO_64 TAP_COUNTER_01(
	.clk(RXCLKDIV), 
	.rst(IDLY_RESET||RESET), 
	.count(ICE_DELAY||ICE_TO_ISERDES[01]), 
	.ud(INC_DELAY||INC_TO_ISERDES[01]), 
	.counter_value(TAP_01)
);
RCB_FRL_COUNT_TO_64 TAP_COUNTER_02(
	.clk(RXCLKDIV), 
	.rst(IDLY_RESET||RESET), 
	.count(ICE_DELAY||ICE_TO_ISERDES[02]), 
	.ud(INC_DELAY||INC_TO_ISERDES[02]), 
	.counter_value(TAP_02)
);
RCB_FRL_COUNT_TO_64 TAP_COUNTER_03(
	.clk(RXCLKDIV), 
	.rst(IDLY_RESET||RESET), 
	.count(ICE_DELAY||ICE_TO_ISERDES[03]), 
	.ud(INC_DELAY||INC_TO_ISERDES[03]), 
	.counter_value(TAP_03)
);
RCB_FRL_COUNT_TO_64 TAP_COUNTER_04(
	.clk(RXCLKDIV), 
	.rst(IDLY_RESET||RESET), 
	.count(ICE_DELAY||ICE_TO_ISERDES[04]), 
	.ud(INC_DELAY||INC_TO_ISERDES[04]), 
	.counter_value(TAP_04)
);

//CIRCUIT TO PRODUCE RESET DELAYED BY 20 CYCLES FOR BIT_ALIGN_MACHINE
integer	K;
always @(posedge RXCLKDIV) begin
	RESET_SM[0] <= RESET;
   for(K = 0; K <= 20 - 1; K = K + 1) begin
		RESET_SM[K+1] <= RESET_SM[K];
   end
end

//DATA INPUT BUFFERS
IBUFDS #(.DIFF_TERM("FALSE"), .IOSTANDARD("LVDS_25")) RX_DATA_IN_00(.O(DATA_RX_BUF[00]), .I(DATA_RX_P[00]), .IB(DATA_RX_N[00]));
IBUFDS #(.DIFF_TERM("FALSE"), .IOSTANDARD("LVDS_25")) RX_DATA_IN_01(.O(DATA_RX_BUF[01]), .I(DATA_RX_P[01]), .IB(DATA_RX_N[01]));
IBUFDS #(.DIFF_TERM("FALSE"), .IOSTANDARD("LVDS_25")) RX_DATA_IN_02(.O(DATA_RX_BUF[02]), .I(DATA_RX_P[02]), .IB(DATA_RX_N[02]));
IBUFDS #(.DIFF_TERM("FALSE"), .IOSTANDARD("LVDS_25")) RX_DATA_IN_03(.O(DATA_RX_BUF[03]), .I(DATA_RX_P[03]), .IB(DATA_RX_N[03]));
IBUFDS #(.DIFF_TERM("FALSE"), .IOSTANDARD("LVDS_25")) RX_DATA_IN_04(.O(DATA_RX_BUF[04]), .I(DATA_RX_P[04]), .IB(DATA_RX_N[04]));

//INPUT DELAY IN DATA PATH
IODELAY #(
		.IDELAY_TYPE("VARIABLE"), .IDELAY_VALUE(0), .ODELAY_VALUE(0), .REFCLK_FREQUENCY(200.00), 
		.HIGH_PERFORMANCE_MODE("TRUE")) 
		IODELAY_RX_DATA_00 (
			.DATAOUT(DATA_RX_IDLY[00]), .IDATAIN(DATA_RX_BUF[00]), .ODATAIN(1'b0), .DATAIN(1'b0), 
			.T(), .CE(ICE_DELAY||ICE_TO_ISERDES[00]), .INC(INC_DELAY||INC_TO_ISERDES[00]), .C(RXCLKDIV), .RST(IDLY_RESET||RESET));
IODELAY #(
		.IDELAY_TYPE("VARIABLE"), .IDELAY_VALUE(0), .ODELAY_VALUE(0), .REFCLK_FREQUENCY(200.00), 
		.HIGH_PERFORMANCE_MODE("TRUE")) 
		IODELAY_RX_DATA_01 (
			.DATAOUT(DATA_RX_IDLY[01]), .IDATAIN(DATA_RX_BUF[01]), .ODATAIN(1'b0), .DATAIN(1'b0), 
			.T(), .CE(ICE_DELAY||ICE_TO_ISERDES[01]), .INC(INC_DELAY||INC_TO_ISERDES[01]), .C(RXCLKDIV), .RST(IDLY_RESET||RESET));
IODELAY #(
		.IDELAY_TYPE("VARIABLE"), .IDELAY_VALUE(0), .ODELAY_VALUE(0), .REFCLK_FREQUENCY(200.00), 
		.HIGH_PERFORMANCE_MODE("TRUE")) 
		IODELAY_RX_DATA_02 (
			.DATAOUT(DATA_RX_IDLY[02]), .IDATAIN(DATA_RX_BUF[02]), .ODATAIN(1'b0), .DATAIN(1'b0), 
			.T(), .CE(ICE_DELAY||ICE_TO_ISERDES[02]), .INC(INC_DELAY||INC_TO_ISERDES[02]), .C(RXCLKDIV), .RST(IDLY_RESET||RESET));
IODELAY #(
		.IDELAY_TYPE("VARIABLE"), .IDELAY_VALUE(0), .ODELAY_VALUE(0), .REFCLK_FREQUENCY(200.00), 
		.HIGH_PERFORMANCE_MODE("TRUE")) 
		IODELAY_RX_DATA_03 (
			.DATAOUT(DATA_RX_IDLY[03]), .IDATAIN(DATA_RX_BUF[03]), .ODATAIN(1'b0), .DATAIN(1'b0), 
			.T(), .CE(ICE_DELAY||ICE_TO_ISERDES[03]), .INC(INC_DELAY||INC_TO_ISERDES[03]), .C(RXCLKDIV), .RST(IDLY_RESET||RESET));
IODELAY #(
		.IDELAY_TYPE("VARIABLE"), .IDELAY_VALUE(0), .ODELAY_VALUE(0), .REFCLK_FREQUENCY(200.00), 
		.HIGH_PERFORMANCE_MODE("TRUE")) 
		IODELAY_RX_DATA_04 (
			.DATAOUT(DATA_RX_IDLY[04]), .IDATAIN(DATA_RX_BUF[04]), .ODATAIN(1'b0), .DATAIN(1'b0), 
			.T(), .CE(ICE_DELAY||ICE_TO_ISERDES[04]), .INC(INC_DELAY||INC_TO_ISERDES[04]), .C(RXCLKDIV), .RST(IDLY_RESET||RESET));
                                                                                        

//M ISERDES IN DATA PATH                                                                                                    
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("MASTER")
	) ISERDES_RX_DATA_00(
		.Q1(DATA_FROM_ISERDES[000]), .Q2(DATA_FROM_ISERDES[001]), .Q3(DATA_FROM_ISERDES[002]), 
		.Q4(DATA_FROM_ISERDES[003]), .Q5(DATA_FROM_ISERDES[004]), .Q6(DATA_FROM_ISERDES[005]), 
		.SHIFTOUT1(SHIFT1[00]), .SHIFTOUT2(SHIFT2[00]), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[00]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(DATA_RX_IDLY[00]), 
		.OCLK(), .SHIFTIN1(), .SHIFTIN2(), .RST(RESET)
	);
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("MASTER")
	) ISERDES_RX_DATA_01(
		.Q1(DATA_FROM_ISERDES[008]), .Q2(DATA_FROM_ISERDES[009]), .Q3(DATA_FROM_ISERDES[010]), 
		.Q4(DATA_FROM_ISERDES[011]), .Q5(DATA_FROM_ISERDES[012]), .Q6(DATA_FROM_ISERDES[013]), 
		.SHIFTOUT1(SHIFT1[01]), .SHIFTOUT2(SHIFT2[01]), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[01]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(DATA_RX_IDLY[01]), 
		.OCLK(), .SHIFTIN1(), .SHIFTIN2(), .RST(RESET)
	);
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("MASTER")
	) ISERDES_RX_DATA_02(
		.Q1(DATA_FROM_ISERDES[016]), .Q2(DATA_FROM_ISERDES[017]), .Q3(DATA_FROM_ISERDES[018]), 
		.Q4(DATA_FROM_ISERDES[019]), .Q5(DATA_FROM_ISERDES[020]), .Q6(DATA_FROM_ISERDES[021]), 
		.SHIFTOUT1(SHIFT1[02]), .SHIFTOUT2(SHIFT2[02]), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[02]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(DATA_RX_IDLY[02]), 
		.OCLK(), .SHIFTIN1(), .SHIFTIN2(), .RST(RESET)
	);
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("MASTER")
	) ISERDES_RX_DATA_03(
		.Q1(DATA_FROM_ISERDES[024]), .Q2(DATA_FROM_ISERDES[025]), .Q3(DATA_FROM_ISERDES[026]), 
		.Q4(DATA_FROM_ISERDES[027]), .Q5(DATA_FROM_ISERDES[028]), .Q6(DATA_FROM_ISERDES[029]), 
		.SHIFTOUT1(SHIFT1[03]), .SHIFTOUT2(SHIFT2[03]), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[03]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(DATA_RX_IDLY[03]), 
		.OCLK(), .SHIFTIN1(), .SHIFTIN2(), .RST(RESET)
	);
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("MASTER")
	) ISERDES_RX_DATA_04(
		.Q1(DATA_FROM_ISERDES[032]), .Q2(DATA_FROM_ISERDES[033]), .Q3(DATA_FROM_ISERDES[034]), 
		.Q4(DATA_FROM_ISERDES[035]), .Q5(DATA_FROM_ISERDES[036]), .Q6(DATA_FROM_ISERDES[037]), 
		.SHIFTOUT1(SHIFT1[04]), .SHIFTOUT2(SHIFT2[04]), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[04]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(DATA_RX_IDLY[04]), 
		.OCLK(), .SHIFTIN1(), .SHIFTIN2(), .RST(RESET)
	);

//S ISERDES IN DATA PATH
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("SLAVE")
	) ISERDES_RX_DATA_00S(
		.Q1(), .Q2(), .Q3(DATA_FROM_ISERDES[006]), .Q4(DATA_FROM_ISERDES[007]), .Q5(), .Q6(), 
		.SHIFTOUT1(), .SHIFTOUT2(), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[00]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(), .OCLK(), 
		.SHIFTIN1(SHIFT1[00]), .SHIFTIN2(SHIFT2[00]), .RST(RESET)
	);
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("SLAVE")
	) ISERDES_RX_DATA_01S(
		.Q1(), .Q2(), .Q3(DATA_FROM_ISERDES[014]), .Q4(DATA_FROM_ISERDES[015]), .Q5(), .Q6(), 
		.SHIFTOUT1(), .SHIFTOUT2(), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[01]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(), .OCLK(), 
		.SHIFTIN1(SHIFT1[01]), .SHIFTIN2(SHIFT2[01]), .RST(RESET)
	);
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("SLAVE")
	) ISERDES_RX_DATA_02S(
		.Q1(), .Q2(), .Q3(DATA_FROM_ISERDES[022]), .Q4(DATA_FROM_ISERDES[023]), .Q5(), .Q6(), 
		.SHIFTOUT1(), .SHIFTOUT2(), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[02]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(), .OCLK(), 
		.SHIFTIN1(SHIFT1[02]), .SHIFTIN2(SHIFT2[02]), .RST(RESET)
	);
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("SLAVE")
	) ISERDES_RX_DATA_03S(
		.Q1(), .Q2(), .Q3(DATA_FROM_ISERDES[030]), .Q4(DATA_FROM_ISERDES[031]), .Q5(), .Q6(), 
		.SHIFTOUT1(), .SHIFTOUT2(), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[03]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(), .OCLK(), 
		.SHIFTIN1(SHIFT1[03]), .SHIFTIN2(SHIFT2[03]), .RST(RESET)
	);
ISERDES_NODELAY #(
		.BITSLIP_ENABLE("TRUE"), .DATA_RATE("DDR"), .DATA_WIDTH(8), .INTERFACE_TYPE("NETWORKING"), 
		.NUM_CE(1), .SERDES_MODE("SLAVE")
	) ISERDES_RX_DATA_04S(
		.Q1(), .Q2(), .Q3(DATA_FROM_ISERDES[038]), .Q4(DATA_FROM_ISERDES[039]), .Q5(), .Q6(), 
		.SHIFTOUT1(), .SHIFTOUT2(), .BITSLIP(BITSLIP_PULSE||BITSLIP_TO_ISERDES[04]), 
		.CE1(1'b1), .CE2(), .CLK(RXCLK), .CLKB(~RXCLK), .CLKDIV(RXCLKDIV), .D(), .OCLK(), 
		.SHIFTIN1(SHIFT1[04]), .SHIFTIN2(SHIFT2[04]), .RST(RESET)
	);
     
endmodule 
